﻿/* Created by Subodh Shrestha
 * Contact: forsubodh@gmail.com */

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace TravelExpertsManagementConsole
{
    public partial class formPackage : Form
    {
        public enum methodcalltype
        {
            add = 0,
            update = 1,
        }

        public formPackage(frmContainer parent)
        {
            InitializeComponent();
            MdiParent = parent;
            setAccessControls(parent.accessLevel);
        }

        public void setAccessControls(int accessLevel)
        {
            switch (accessLevel)
            {
                case 3:
                    btnNew.Enabled = false;
                    btnDelete.Enabled = false;
                    btnSubmit.Enabled = false;
                    break;
                default:
                    break;
            }
        }

        private void Package_Load(object sender, EventArgs e)
        {
            refreshList();
        }

        private void Package_FormClosing(object sender, FormClosingEventArgs e)
        {
            frmContainer parent = (frmContainer)MdiParent;

            parent.childPackage = null;
            
        }

        private void refreshList()
        {
            try
            {
                DataAccess<Package> myDataAccess = new DataAccess<Package>();
                lbPackage.DataSource = myDataAccess.select();

                lbProdIncluded.DataSource = ((Package)lbPackage.SelectedItem).PkgProducts;
                lbSuppliers.DataSource = ((Product)lbProdIncluded.SelectedItem).SupplierList;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void lbPackage_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (lbPackage.SelectedIndex == -1)
            {
                return;
            }
            Package selectedPkg = (Package)lbPackage.SelectedItem;
            tbPkgId.Text = selectedPkg.PkgId.ToString();
            tbPkgName.Text = selectedPkg.PkgName;
            tbPkgDest.Text = selectedPkg.PkgDestination;
            tbPkgDesc.Text = selectedPkg.PkgDesc;
            dtpPkgStartDate.Value = selectedPkg.PkgStartDate;
            dtpPkgEndDate.Value = selectedPkg.PkgEndDate;
            tbPkgBasePrice.Text = selectedPkg.PkgBasePrice.ToString();
            tbPkgComm.Text = selectedPkg.PkgCommission.ToString();
            lbProdIncluded.DataSource = ((Package)lbPackage.SelectedItem).PkgProducts;
            if (lbProdIncluded.SelectedIndex != -1)
            {
                lbSuppliers.DataSource = ((Product)lbProdIncluded.SelectedItem).SupplierList;
            }
            else
            {
                //clears Supplier list box if none of the Products are selected
                lbSuppliers.DataSource = null;
            }
        }

        private void btnNew_Click(object sender, EventArgs e)
        {
            tbPkgId.Text = "";
            tbPkgName.Text = "";
            tbPkgDest.Text = "";
            tbPkgDesc.Text = "";
            dtpPkgStartDate.Value = DateTime.Now;
            dtpPkgEndDate.Value = DateTime.Now;
            tbPkgBasePrice.Text = "";
            tbPkgComm.Text = "";
            lbPackage.SelectedIndex = -1;
            lbProdIncluded.DataSource = null;
            lbSuppliers.DataSource = null;
        }

        private void btnSubmit_Click(object sender, EventArgs e)
        {
            if (!validateInput(methodcalltype.add))
            {
                return;
            }
            try
            {
                DataAccess<Package> myDataAccess = new DataAccess<Package>();
                Package newPackage = new Package();
                newPackage.PkgName = tbPkgName.Text;
                newPackage.PkgDesc = tbPkgDesc.Text;
                newPackage.PkgDestination = tbPkgDest.Text;
                newPackage.PkgStartDate = dtpPkgStartDate.Value;
                newPackage.PkgEndDate = dtpPkgEndDate.Value;
                newPackage.PkgBasePrice = Decimal.Parse(tbPkgBasePrice.Text);
                newPackage.PkgCommission = Decimal.Parse(tbPkgComm.Text);
                newPackage.PkgProducts = new List<Product>();
                foreach (Product prod in lbProdIncluded.Items)
                {
                    newPackage.PkgProducts.Add(prod);
                }
                myDataAccess.Add(newPackage);
                
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }

            refreshList();
        }

        private bool validateInput(methodcalltype func)
        {
            string errMsg = "";
            if (func == methodcalltype.add)
            {
                if (tbPkgId.Text != "")
                {
                    errMsg += "Cannot create duplicate package" + Environment.NewLine;
                }
            }
            if (tbPkgName.Text == "")
            {
                errMsg += "Please enter a Package Name" + Environment.NewLine;
            }
            else
            {
                Decimal num;
                if (Decimal.TryParse(tbPkgName.Text, out num))
                {
                    errMsg += "Package Name must be a string" + Environment.NewLine;
                }
            }

            if (tbPkgDesc.Text == "")
            {
                errMsg += "Please enter a Package Description" + Environment.NewLine;
            }
            else
            {
                Decimal num;
                if (Decimal.TryParse(tbPkgDesc.Text, out num))
                {
                    errMsg += "Package Description must be a string" + Environment.NewLine;
                }
            }

            if (tbPkgDest.Text == "")
            {
                errMsg += "Please enter a Package Destination" + Environment.NewLine;
            }
            else
            {
                Decimal num;
                if (Decimal.TryParse(tbPkgDest.Text, out num))
                {
                    errMsg += "Package Destination must be a string" + Environment.NewLine;
                }
            }

            if (tbPkgBasePrice.Text == "")
            {
                errMsg += "Please enter a Base Price" + Environment.NewLine;
            }
            else
            {
                Decimal basePrice = 0;
                Decimal agencyComm = 0;
                if (!Decimal.TryParse(tbPkgBasePrice.Text, out basePrice))
                {
                    errMsg += "Base Price must be numeric" + Environment.NewLine;
                }
                else
                {
                    if (tbPkgComm.Text != "")
                    {
                        if (!Decimal.TryParse(tbPkgComm.Text, out agencyComm))
                        {
                            errMsg += "Agency Commission must be numeric" + Environment.NewLine;
                        }
                        else
                        {
                            if (agencyComm > basePrice)
                            {
                                errMsg += "Agency Commission can not be greater than Base Price" + Environment.NewLine;
                            }
                        }

                    }
                }
            }

            if (dtpPkgEndDate.Value <= dtpPkgStartDate.Value)
            {
                errMsg += "Package End Date must be after Package Start date" + Environment.NewLine;
            }

            if (errMsg == "")
            {
                return true;
            }
            else
            {
                MessageBox.Show(errMsg);
                return false;
            }
        }

        private void formPackage_Enter(object sender, EventArgs e)
        {
            cbAllProducts.DataSource = DataAccess<Package>.setAllProducts();
            refreshList();
        }

        private void cbAllProducts_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (cbAllProducts.SelectedIndex == -1)
            {
                return;
            }
            cbSuppInProducts.DataSource = ((Product)cbAllProducts.SelectedItem).SupplierList;
        }

        private void lbProdIncluded_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (lbProdIncluded.SelectedIndex == -1)
            {
                return;
            }
            lbSuppliers.DataSource = ((Product)lbProdIncluded.SelectedItem).SupplierList;
        }

        private void addToProdSuppliers_Click(object sender, EventArgs e)
        {
            if (cbAllProducts.SelectedIndex == -1)
            {
                return;
            }
            Product selectedProduct = new Product(); 
            selectedProduct.ProductID = ((Product)cbAllProducts.SelectedItem).ProductID;
            selectedProduct.ProductName = ((Product)cbAllProducts.SelectedItem).ProductName;
            selectedProduct.SupplierList = new List<Supplier>();
            Supplier selectedSupplier = (Supplier)cbSuppInProducts.SelectedItem;
            selectedProduct.SupplierList.Add(selectedSupplier);
            
            List<Product> productList;
            List<Supplier> supplierList;
            if ((List<Product>)lbProdIncluded.DataSource != null)
            {
                productList = (List<Product>)lbProdIncluded.DataSource;
                supplierList = (List<Supplier>)lbSuppliers.DataSource;
            }
            else
            {
                productList = new List<Product>();
                
            }
            //check if the product-to-add already exists in the product's supplier list
            Product findMatchProduct = productList.Find(delegate(Product p) { return (p.ProductID == selectedProduct.ProductID); });

            //Product-Supplier is being added for the first time
            if (findMatchProduct == null)
            {
                productList.Add(selectedProduct);
                lbProdIncluded.DataSource = productList;
                lbSuppliers.DataSource = selectedProduct.SupplierList;
            }else
            {
                //Product exists
                //check if the supplier exists or not
                Supplier findMatchSupplier = findMatchProduct.SupplierList.Find(delegate(Supplier s){ return s.SupplierId == selectedSupplier.SupplierId; });
                if (findMatchSupplier == null)
                {
                    //if the supplier doesn't exist, add to the product in the package
                    findMatchProduct.SupplierList.Add(selectedSupplier);
                }
            }
            ((CurrencyManager)lbProdIncluded.BindingContext[lbProdIncluded.DataSource]).Refresh();
            ((CurrencyManager)lbSuppliers.BindingContext[lbSuppliers.DataSource]).Refresh();
        }

        private void removeFromProdSuppliers_Click(object sender, EventArgs e)
        {
            if (cbAllProducts.DataSource == null)
            {
                return;
            }
            if (cbAllProducts.SelectedIndex == -1)
            {
                return;
            }
            if (lbSuppliers.Items.Count == 1)
            {
                //remove the product as well if only one supplier is present
                Supplier selectedSupplier = (Supplier)lbSuppliers.SelectedItem;
                List<Supplier> suppList = (List<Supplier>)lbSuppliers.DataSource;
                suppList.Remove(selectedSupplier);
                Product selectedProduct = (Product)lbProdIncluded.SelectedItem;
                List<Product> prodList = (List<Product>)lbProdIncluded.DataSource;
                prodList.Remove(selectedProduct);
            }
            else
            {
                //remove only the supplier if more than one suppliers are present
                Supplier selectedSupplier = (Supplier)lbSuppliers.SelectedItem;
                List<Supplier> suppList = (List<Supplier>)lbSuppliers.DataSource;
                suppList.Remove(selectedSupplier);
            }
            ((CurrencyManager)lbProdIncluded.BindingContext[lbProdIncluded.DataSource]).Refresh();
            ((CurrencyManager)lbSuppliers.BindingContext[lbSuppliers.DataSource]).Refresh();
        }

        private void btnDelete_Click(object sender, EventArgs e)
        {
            if (lbPackage.SelectedIndex == -1)
            {
                MessageBox.Show("Please Select a Package");
            }
            //delete entries for selected Package from Package_Products_Suppliers;
            Package selectedPackage = (Package)lbPackage.SelectedItem;

            try
            {
                DataAccess<Package> myDataAccess = new DataAccess<Package>();
                myDataAccess.Delete(selectedPackage);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }

            refreshList();
        }

        private void btnUpdate_Click(object sender, EventArgs e)
        {
            if (lbPackage.SelectedIndex == -1)
            {
                MessageBox.Show("Please select a Package");
                return;
            }
            if (!validateInput(methodcalltype.update))
            {
                return;
            }
            try
            {
                DataAccess<Package> myDataAccess = new DataAccess<Package>();
                Package updatePackage = new Package();
                updatePackage.PkgId = int.Parse(tbPkgId.Text);
                updatePackage.PkgName = tbPkgName.Text;
                updatePackage.PkgDesc = tbPkgDesc.Text;
                updatePackage.PkgDestination = tbPkgDest.Text;
                updatePackage.PkgStartDate = dtpPkgStartDate.Value;
                updatePackage.PkgEndDate = dtpPkgEndDate.Value;
                updatePackage.PkgBasePrice = Decimal.Parse(tbPkgBasePrice.Text);
                updatePackage.PkgCommission = Decimal.Parse(tbPkgComm.Text);
                updatePackage.PkgProducts = new List<Product>();
                foreach (Product prod in lbProdIncluded.Items)
                {
                    updatePackage.PkgProducts.Add(prod);
                }
                myDataAccess.Update(updatePackage);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }

            refreshList();
        }
    }
}
